﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace bianyi
{
    public class Builtin
    {
        public static Value nyx_builtin_print(Runtime rt,
                            List<Context> ctxChain,
                            List<Value> args)
        {
            foreach (var arg in args)
            {
                Console.WriteLine(arg.data);
                Console.WriteLine(arg.data);
            }
            return new Value(ValueType.Int, (int)args.Count());
        }

        public static Value nyx_builtin_createVmFromJsonFile(Runtime rt,
                           List<Context> ctxChain,
                           List<Value> args)
        {
            if (args.Count < 1)
            {
                Console.WriteLine("ArgumentError: expects 1 argument but got {0}", args.Count());
            }
            string strfile = args[0].data.ToString();

            ConsoleApp1.function.json.createVmFromJsonFile(strfile);

            return new Value(ValueType.Int, (int)args.Count());
        }

        public static Value nyx_builtin_createVmFromDb(Runtime rt,
                             List<Context> ctxChain,
                             List<Value> args)
        {
            if (args.Count < 3)
            {
                Console.WriteLine("ArgumentError: expects 3 argument but got {0}", args.Count());
            }
            string server = args[0].data.ToString();
            string db = args[1].data.ToString();
            string strTable = args[2].data.ToString();

            ConsoleApp1.function.sqlserver.createVmFromDb(server, db, strTable);

            return new Value(ValueType.Int, (int)args.Count());
        }

        public static Value nyx_builtin_checkConnect(Runtime rt,
                           List<Context> ctxChain,
                           List<Value> args)
        {
            if (args.Count < 1)
            {
                Console.WriteLine("ArgumentError: expects 2 argument but got {0}", args.Count());
            }
            string server = args[0].data.ToString();

            ConsoleApp1.function.sqlserver.checkConnect(server);

            return new Value(ValueType.Int, (int)args.Count());
        }

        public static Value nyx_builtin_getTables(Runtime rt,
                          List<Context> ctxChain,
                          List<Value> args)
        {
            if (args.Count < 2)
            {
                Console.WriteLine("ArgumentError: expects 2 argument but got {0}", args.Count());
            }
            string server = args[0].data.ToString();
            string db = args[1].data.ToString();

            ConsoleApp1.function.sqlserver.getTables(server, db);

            return new Value(ValueType.Int, (int)args.Count());
        }

        public static Value nyx_builtin_println(Runtime rt, List<Context> ctxChain, List<Value> args)
        {
            foreach (var arg in args)
            {
                Console.WriteLine(arg.data);
                Console.WriteLine(arg.data);
            }
            return new Value(ValueType.Int, (int)args.Count());
        }

        public static Value nyx_builtin_input(Runtime rt, List<Context> ctxChain, List<Value> args)
        {
            Value result = new Value();

            string str;
            str = Console.ReadLine();
            result.type = ValueType.String;
            result.data = str;
            return result;
        }

        public static Value nyx_builtin_typeof(Runtime rt, List<Context> ctxChain, List<Value> args)
        {
            if (args.Count() != 1)
            {
                Console.WriteLine("ArgumentError: expects one argument but got {0}", args.Count());
            }
            Value result = new Value();
            result.type = ValueType.String;
            switch (args[0].type)
            {
                case ValueType.Bool:
                    //result.data = ("bool");
                    result.data = "bool";
                    break;

                case ValueType.Double:
                    result.data = ("double");
                    break;

                case ValueType.Int:
                    result.data = ("int");
                    break;

                case ValueType.String:
                    result.data = ("string");
                    break;

                case ValueType.Null:
                    result.data = ("null");
                    break;

                case ValueType.Char:
                    result.data = ("char");
                    break;

                case ValueType.Array:
                    result.data = ("array");
                    break;

                default:
                    Console.WriteLine("TypeError: unknown type!");
                    break;
            }
            return result;
        }

        public static Value nyx_builtin_length(Runtime rt, List<Context> ctxChain, List<Value> args)
        {
            if (args.Count() != 1)
            {
                Console.WriteLine("ArgumentError: expects one argument but got {0}", args.Count());
            }

            if (args[0].type == ValueType.String)
            {
                return new Value(ValueType.Int, args[0].data.ToString().Length);
            }
            if (args[0].type == ValueType.Array)
            {
                return new Value(ValueType.Int, ((Array)(args[0].data)).Length);
            }

            Console.WriteLine(
                "TypeError: unexpected type of arguments, requires string type or array type");
            return null;
        }
    }
}